﻿using System;
using System.Xml;
using System.IO;
using System.Web;
using System.Net;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;
namespace DataLibrary
{
    public class AutoGetNews
    {
        private String m_myconnecString;
        public AutoGetNews(String myconnecString) {
            this.m_myconnecString = myconnecString;
        }

        public  void GetNews(tbl_website web)
        {
            StringBuilder sb = GetHtml(web.Website);

            if (sb != null)
            {
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(sb.ToString());
                List<ItemInfo> lstUrl = GetUrls(web.Website, sb.ToString());
                foreach (ItemInfo item in lstUrl)
                {
                    GetContent(item, web);
                }
            }
        }

        private tbl_Auto GetContent(ItemInfo info, tbl_website web)
        {
            Ctbl_Auto auto = new Ctbl_Auto(this.m_myconnecString);
            tbl_Auto news = null;
            StringBuilder sb = GetHtml(info.Url);
            string xpath = web.Xpath;
            if (sb != null)
            {
                HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                doc.LoadHtml(sb.ToString());
                if (xpath.ToLower().Contains("@id") == true || xpath.ToLower().Contains("@") == false)
                {
                    HtmlNode node = doc.DocumentNode.SelectSingleNode(web.Xpath);

                    if (node != null)
                    {
                       
                        CreateNew(info, auto, news, node,web);
                    }
                }
                else if (xpath.ToLower().Contains("@id") == false && xpath.ToLower().Contains("@") == true)
                {
                    if (doc.DocumentNode.SelectNodes(xpath) != null)
                    {

                        if (doc.DocumentNode.SelectNodes(xpath).Count == 1)
                        {
                            HtmlNode node = doc.DocumentNode.SelectSingleNode(web.Xpath);

                            if (node != null)
                            {
                                CreateNew(info, auto, news, node, web);
                            }
                        }
                        else if (doc.DocumentNode.SelectNodes(xpath).Count > 1)
                        {
                            foreach (HtmlNode node in doc.DocumentNode.SelectNodes(xpath))
                            {
                                if (node.InnerText.Contains(info.Title))
                                {
                                    CreateNew(info, auto, news, node, web);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            return news;
        }

        private void CreateNew(ItemInfo info, Ctbl_Auto auto, tbl_Auto news, HtmlNode node, tbl_website web)
        {
            if (auto.GetListNews(web.Id).Find(p => p.Url.Trim().ToLower().CompareTo(info.Url.Trim().ToLower()) == 0) == null)
            {

                news = new tbl_Auto();
                news.Content = ModifyContentHtml(node.OuterHtml, info);
                news.Url = info.Url;
                news.Title = info.Title;
                news.Pubdate = DateTime.Now;
                news.WebsiteId = web.Id;
                news.Description = info.Description;
                auto.InsertOnSubmit(news);
                
            }
        }

        private List<ItemInfo> GetUrls(string url, string doc)
        {
            List<ItemInfo> rst = null;
            rst = new List<ItemInfo>();
            XmlDocument xmlDoc = new XmlDocument();

            try
            {
                StringBuilder sb = GetHtml(url);
                if (sb != null)

                    xmlDoc.LoadXml(sb.ToString());
            }
            catch
            {
                xmlDoc.Load(url);
            }
            foreach (XmlNode node in xmlDoc.SelectNodes("//item"))
            {
                ItemInfo item = new ItemInfo();

                for (int i = 0; i < node.ChildNodes.Count; i++)
                {
                    if (node.ChildNodes[i].Name.ToLower().Trim().CompareTo("title") == 0)
                    {
                        item.Title = node.ChildNodes[i].InnerText;
                    }

                    if (node.ChildNodes[i].Name.ToLower().Trim().CompareTo("link") == 0)
                    {
                        item.Url = node.ChildNodes[i].InnerText;
                    }
                    if (node.ChildNodes[i].Name.ToLower().Trim().CompareTo("description") == 0)
                    {
                        item.Description = node.ChildNodes[i].InnerText;
                    }

                }

                rst.Add(item);
            }

            return rst;
        }

        private string ModifyContentHtml(string sHtml, ItemInfo info)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(sHtml);
            Uri uri = new Uri(info.Url);

            string host = uri.Host;

            string shttp = "http://";
            if (doc.DocumentNode.SelectNodes("//a[@href]") != null)
            {
                foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//a[@href]"))
                {
                    string href = node.Attributes["href"].Value;
                    if (href.Contains(shttp) == false)
                    {
                        node.Attributes["href"].Value = shttp + host + "/" + href;
                    }
                }
            }
            if (doc.DocumentNode.SelectNodes("//img[@src]") != null)
            {
                foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//img[@src]"))
                {
                    string href = node.Attributes["src"].Value.ToLower();
                    if (href.Contains(shttp) == false)
                    {
                        node.Attributes["src"].Value = shttp + host + "/" + href;
                        string s = node.XPath;
                    }
                }
            }

            if (doc.DocumentNode.SelectNodes("//script") != null)
            {
                foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//script"))
                {
                        node.Remove();
                }
            }

            foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//*"))
            {
                if (node.InnerText.Trim().ToLower().CompareTo(info.Title.Trim().ToLower()) == 0)
                {
                    node.Remove();

                    break;
                }
            }
            return doc.DocumentNode.InnerHtml;
        }

        private StringBuilder GetHtml(string url)
        {
            try
            {
                StringBuilder sb = new StringBuilder();

                byte[] buf = new byte[8192];


                HttpWebRequest request = (HttpWebRequest)
                    WebRequest.Create(url);

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                Stream resStream = response.GetResponseStream();

                string tempString = null;
                int count = 0;

                do
                {

                    count = resStream.Read(buf, 0, buf.Length);


                    if (count != 0)
                    {

                        tempString = Encoding.UTF8.GetString(buf, 0, count);


                        sb.Append(tempString);
                    }
                }
                while (count > 0);

                return sb;
            }
            catch
            {
                return null;
            }
        }
    }

    class ItemInfo
    {
        string title;
        string url;
        DateTime pubDate;

        public DateTime PubDate
        {
            get { return pubDate; }
            set { pubDate = value; }
        }

        public string Url
        {
            get { return url; }
            set { url = value; }
        }

        public string Title
        {
            get { return title; }
            set { title = value; }
        }

        string host;

        public string Host
        {
            get { return host; }
            set { host = value; }
        }

        public string Description
        {
            get;
            set;
        }
    }

}
